package org.budo.spring.mvc.view.jphp.loader;

import java.io.File;
import java.io.FileNotFoundException;

import org.budo.support.assertion.Assert;
import org.budo.support.lang.util.StringUtil;
import org.budo.support.slf4j.Slf4j;
import org.budo.support.spring.io.resource.BudoClassPathResource;
import org.budo.support.spring.io.util.ResourceUtil;
import org.slf4j.Logger;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

/**
 * @author li
 */
public class DefaultJphpTemplateLoader implements JphpTemplateLoader {
    private static final Logger log = Slf4j.getLogger();

    private String[] templateLoaderPaths;

    public Resource loadTemplate(String url) {
        Resource resource = this.loadTemplateResource(url);

        if (null != resource) {
            return resource;
        }

        String error = "template Resource not found, " //
                + ", url=" + url //
                + ", templateLoaderPaths=" + StringUtil.join(templateLoaderPaths);
        throw new RuntimeException(new FileNotFoundException(error));
    }

    private Resource loadTemplateResource(String url) {
        for (String templateLoaderPath : templateLoaderPaths) {
            if (templateLoaderPath.startsWith("classpath:")) {
                String resourcePath = templateLoaderPath.substring(10) + url;
                ClassPathResource classPathResource = new ClassPathResource(resourcePath);
                if (classPathResource.exists() && classPathResource.isReadable()) {
                    return classPathResource;
                }
            }
        }

        throw new RuntimeException("templateLoaderPaths = " + StringUtil.join(templateLoaderPaths) + ", url=" + url);
    }

    @SuppressWarnings("unused")
    private Resource ssss(String url) {
        File webappFile = new File("src" + File.separatorChar + "main" + File.separatorChar + "webapp" + File.separatorChar + url);
        if (webappFile.exists() && webappFile.canRead()) {
            return new FileSystemResource(webappFile);
        }

        File mainFile = new File("src" + File.separatorChar + "main" + File.separatorChar + "resources" + File.separatorChar + url);
        if (mainFile.exists() && mainFile.canRead()) {
            return new FileSystemResource(mainFile);
        }

        File testFile = new File("src" + File.separatorChar + "test" + File.separatorChar + "resources" + File.separatorChar + url);
        if (testFile.exists() && testFile.canRead()) {
            return new FileSystemResource(testFile);
        }

        BudoClassPathResource classPathResource = new BudoClassPathResource(url);
        if (classPathResource.exists() && classPathResource.isReadable()) {
            log.info("url=" + url + ", classPathResource=" + classPathResource + ", uri=" + ResourceUtil.getURI(classPathResource));
            return classPathResource;
        }

        return null;
    }

    public String[] getTemplateLoaderPaths() {
        return templateLoaderPaths;
    }

    public void setTemplateLoaderPaths(String[] templateLoaderPaths) {
        Assert.notNull(templateLoaderPaths, "templateLoaderPaths is null");
        for (String templateLoaderPath : templateLoaderPaths) {
            Assert.notEmpty(templateLoaderPath, "templateLoaderPath is null or empty");

            if (templateLoaderPath.startsWith("classpath:")) {
                //
            } else {
                throw new RuntimeException("templateLoaderPath [" + templateLoaderPath + "] must start with classpath:");
            }
        }
        this.templateLoaderPaths = templateLoaderPaths;
    }
}